package trading.algo.BullTask;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import trading.algo.CancelOrderTask;
import trading.algo.OpenOrdersTask;
import trading.algo.TimerKillerTask;
import trading.bo.DBAccessorBO;
import trading.bo.EmailAccessorBO;
import trading.bo.IBAccessorBO;
import trading.dataentry.MonitoredStocks;
import trading.dataentry.StockPositionOrOrder;
import trading.util.Constants;

public class PositionProtectionCheckTask extends TimerTask {

	private IBAccessorBO ibAccessorBO;
	private DBAccessorBO dbAccessorBO;
	private EmailAccessorBO emailAccessorBO;
	
	public PositionProtectionCheckTask(IBAccessorBO ibAccessorBO, DBAccessorBO dbAccessorBO, EmailAccessorBO emailAccessorBO) {
		this.ibAccessorBO = ibAccessorBO;
		this.dbAccessorBO = dbAccessorBO;
		this.emailAccessorBO = emailAccessorBO;
	}
	
	@Override
	public void run() {
        // Step 1: check UVXY positions
		List<StockPositionOrOrder> stockPositions = this.dbAccessorBO.getPortfolioStockPositions();
		int UVXYPositionSize = 0;
		for (StockPositionOrOrder stockPosition : stockPositions) {
			if (stockPosition.getTicker().equals(MonitoredStocks.TICKERS.UVXY.name())) {
				UVXYPositionSize = Integer.parseInt(stockPosition.getQuantity());
			}
		}
		// because it's short position
		UVXYPositionSize *= -1;
		
		// Step 2: check open mkt stock short orders
		List<StockPositionOrOrder> stockOrders = this.dbAccessorBO.getOpenNonTrailStockOrder();
		for (StockPositionOrOrder stockOrder : stockOrders) {
			if (stockOrder.getTicker().equals(MonitoredStocks.TICKERS.UVXY.name())
					&& !stockOrder.isLimitOrder()) {
				UVXYPositionSize += Integer.parseInt(stockOrder.getQuantity());
			}
		}
		
		// Step 3: check trail order size
		List<StockPositionOrOrder> trailOrders = this.dbAccessorBO.getOpenTrailOrder();
		int UVXYTrailOrderSize = 0;
		for (StockPositionOrOrder trailOrder : trailOrders) {
			if (trailOrder.getTicker().equals(MonitoredStocks.TICKERS.UVXY.name())) {
				UVXYTrailOrderSize += Integer.parseInt(trailOrder.getQuantity());
			}
		}
		
		// Step 3: create protection orders if necessary, or cancel unnecessary orders
		if (UVXYPositionSize > UVXYTrailOrderSize) {
			MonitoredStocks UVXYstat = this.dbAccessorBO.getMonitoredStockData(MonitoredStocks.TICKERS.UVXY.name());
			double trailAmount = UVXYstat.getHistoricalLow() * Constants.Algo.BULL_SHORT_PROTECTION_PERCENTAGE / 100;
			STKShortProtectionOrderTask shortPositionProtectOrderTask = new STKShortProtectionOrderTask(MonitoredStocks.TICKERS.UVXY.name(), UVXYPositionSize - UVXYTrailOrderSize, this.ibAccessorBO, emailAccessorBO, trailAmount, UVXYstat.getHistoricalLow() + trailAmount);
			shortPositionProtectOrderTask.run();
		} else if (UVXYPositionSize < UVXYTrailOrderSize) {
			Timer timer = new Timer();
			int taskID = 0;
			CancelOrderTask cancelOrderTask = new CancelOrderTask(ibAccessorBO, emailAccessorBO, Integer.parseInt(trailOrders.get(0).getOrderId()));
			timer.schedule(cancelOrderTask, taskID * 1000);
			taskID += 2;
			
			OpenOrdersTask openOrdersTask = new OpenOrdersTask(ibAccessorBO, dbAccessorBO);
			timer.schedule(openOrdersTask, taskID * 1000);
			taskID += 1;
			
			PositionProtectionCheckTask protectionCheckTask = new PositionProtectionCheckTask(ibAccessorBO, dbAccessorBO, emailAccessorBO);
			timer.schedule(protectionCheckTask, taskID * 1000);
			taskID += 15;
			
			TimerKillerTask timerKillerTask = new TimerKillerTask(timer);
			timer.schedule(timerKillerTask, taskID * 1000);
		}
	}

}
